<template>
  <div>
    <!-- 应用配置表单 -->
    <a-form-model ref="configForm" :model="configForm.app" :rules="rules">
      <a-row :gutter="32">
        <a-col :span="12">
          <a-form-model-item label="应用名称" prop="name">
            <a-input v-model="configForm.app.name" placeholder="请输入名称" />
          </a-form-model-item>
        </a-col>
        <a-col :span="12">
          <a-form-model-item label="联系人" prop="contact">
            <a-input v-model="configForm.app.contact" placeholder="请输入联系人，存在多个联系人请用'、'分隔" />
          </a-form-model-item>
        </a-col>
      </a-row>
      <a-row>
        <a-form-model-item label="联系电话" prop="mobile">
          <a-input v-model="configForm.app.mobile" placeholder="请输入联系电话" />
        </a-form-model-item>
      </a-row>
      <a-row>
        <a-form-model-item label="接入原因" prop="remark">
          <a-input v-model="configForm.app.remark" placeholder="请输入原因" type="textarea" />
        </a-form-model-item>
      </a-row>
    </a-form-model>
    <a-layout>
      <!-- 接口模块目录 -->
      <a-layout-sider width="300px" :class="{ aside_main_show: !asideStatus }">
        <a-row>
          模块目录
        </a-row>
        <a-row>
          <a-input-search v-model="searchValue" style="margin-bottom: 8px" placeholder="请输入" @change="onSearch" allow-clear />
        </a-row>
        <a-row>
          <a-directory-tree
            ref="tree"
            v-loading="loading1"
            :tree-data="contentsData"
            :expandedKeys="expandedKeys"
            :auto-expand-parent="autoExpandParent"
            @select="handleNodeClick"
            @expand="onExpand"
            :replace-fields="replaceFields"
          />
        </a-row>
      </a-layout-sider>
      <!-- 接口数据表格 -->
      <a-layout-content>
        <!-- aside侧边栏按钮 -->
        <div class="aside_open_close" style="left: 0;top: 40%;" @click="asideChange">
          <a-icon type="left" v-if="asideOpen"/>
          <a-icon type="right" v-else/>
        </div>
        <a-table
          ref="table"
          v-loading="loading2"
          style="position: relative; left: 18px; top: -60px;"
          :columns="columns"
          :dataSource="tableData"
          :pagination="false"
          :scroll="{ x: 600, y: 500 }"
          :default-sort="{ prop: 'id', order: 'ascending' }"
          :row-selection="{ selectedRows: selectedRows, selectedRowKeys: selectedRowKeys, onChange: onSelectChange }"
          bordered
        />
        <!--下面展示总共条数和切换页面-->
        <div class="block">
          <a-pagination
            v-show="total > 0"
            show-size-changer
            layout="total, prev, pager, next, sizes"
            style="position: relative; left: 18px; top: -60px;"
            :total="total"
            :page-size-options="[10, 20, 30, 40, 50]"
            v-model:current="pageForm.pageNum"
            :page-size="pageForm.pageSize"
            :show-total="total => `共${total}条`"
            @change="handleCurrentChange"
            @showSizeChange="handleSizeChange"
          >
            <template #buildOptionText="props">
              <span>{{ props.value }}条/页</span>
            </template>
          </a-pagination>
        </div>
      </a-layout-content>
    </a-layout>
    <div slot="footer">
      <a-button @click="cancel">取 消</a-button>
      <a-button type="primary" @click="submitForm">保 存</a-button>
    </div>
  </div>
</template>
<script>
import { listModule, listInfo, getInfo, getConfig, addConfig, editConfig } from '@/api/system/outapi/manage'

const dataList = []
const generateList = (data) => {
    for (let i = 0; i < data.length; i++) {
        const node = data[i]
        const id = node.id
        const moduleCname=node.moduleCname
        dataList.push({ id, moduleCname: moduleCname })
        if (node.children) {
            generateList(node.children)
        }
    }
}
const getParentKey = (key, tree) => {
  let parentKey
  for (let i = 0; i < tree.length; i++) {
    const node = tree[i]
    if (node.children) {
      if (node.children.some((item) => item.id === key)) {
        parentKey = node.id
      } else if (getParentKey(key, node.children)) {
        parentKey = getParentKey(key, node.children)
      }
    }
  }
  return parentKey
}
const setStyleDisplay = (key, nodes) => {
  let nums = 0
  for (let data of nodes) {
    let bl = false
    if (data.moduleCname.indexOf(key) > -1) {
      bl = true
      nums += 1
    }
    if (!!data.children) {
      if (data.children.length > 0) {
        let count = setStyleDisplay(key, data.children)
        // 如果想 子节点有key 即使父节点没有key也显示的话 添加下面的语句 
        nums += count
        if (!bl && count == 0) {
          bl = false
        } else {
          bl = true
        }
      }
    }
    if (bl) {
      delete data['style']
    } else {
      data['style'] = 'display: none'
    }
  }
  return nums
}

export default {
  props: ['configIds','showDia'],
  data() {
    // 表单校验数据类型
    const isNum = (rule, value, callback) => { // 参数顺序必须如
      let reg = /^[0-9]{11}$/;
      if (reg.test(value)) {
        callback()
      } else {
        callback(new Error("必须为11位整数"))
      }
    }
    return {
      loading1: false, // 目录遮罩层
      loading2: false, // 表格遮罩层
      asideStatus: true, // 侧边栏开关
      asideOpen: true, // 侧边栏按钮
      show: this.showDia, // 弹窗开关
      total: 0, // 表格数据总条数
      id: this.configIds,
      vueId: null,
      searchValue: '', // 搜索框输入内容
      contentsData: [], // 目录数据
      tableData: [], // 表格数据
      selectedRows: [], // 表格选择数据数组
      selectedRowKeys: [], // 表格选中Key值数组
      expandedKeys: [], // 目录展开节点数组
      autoExpandParent: true,
      columns: [{ // 表格内容
        title: '接口名称',
        dataIndex: 'apiName',
        key: 'apiName',
        align: 'left'
      },{
        title: '请求接口地址',
        dataIndex: 'requestUrl',
        key: 'requestUrl',
        align: 'left'
      }],
      pageForm: { // 页面对象
        pageNum: 1,
        pageSize: 10
      },
      replaceFields: { // 节点结构
        title: 'moduleCname',
        key: 'id',
        children: 'children'
      },
      moduleForm: { // 目录表单对象
        id: null,
        moduleName: null,
        moduleCname: null,
        parentId: null,
        remark: null,
        createTime: null, // 不传值
        createBy: null, // 不传值
        updateBy: null, // 不传值
        updateTime: null // 不传值
      },
      infoParams: { // 接口查询表单对象
        pageNum: null,
        pageSize: null,
        id: null,
        apiName: null,
        apiCname: null,
        requestUrl: null,
        moduleId: null,
        apiStatus: null,
        requestMethod: null,
        requestParam: null
      },
      configForm: { // 应用接口配置表单
        app: {
          id: null,
          appId: null, // 不传值
          name: null,
          secKey: null, // 不传值
          mobile: null, // 不传值
          contact: null,
          remark: null,
          createTime: null, // 不传值
          createBy: null // 不传值
        },
        apiList: []
      },
      rules: { // 表单规则
        name: [
          { required: true, message: '应用名称不能为空', trigger: 'blur' }
        ],
        contact: [
          { required: true, message: '联系人不能为空', trigger: 'blur' }
        ],
        mobile: [
          { required: true, message: '联系电话不能为空', trigger: 'blur' },
          { validator: isNum, message: "联系电话必须为11位自然数", trigger: 'blur' }
        ],
        remark: [
          { required: true, message: '接入原因不能为空', trigger: 'blur' }
        ]
      }
    }
  },
  name: "config-api",
  watch: {
    showDia(val) {
      if (val === true) {
        this.initVue()
      }
    }
  },
  created() {
    this.initVue()
  },
  methods: {
    initVue() { // 初始化页面
      this.initForm()
      this.selectedRows = []
      this.selectedRowKeys = []
      this.show = this.showDia
      this.id = this.configIds
      this.vueId = null
      this.pageForm.pageNum = 1
      this.pageForm.pageSize = 10
      this.getModuleData()
      this.getInfoData()
      if (this.id != null) {
        this.loading2 = true
        getConfig(this.id).then(response => {
          this.configForm.app = response.data.app
          this.configForm.apiList = response.data.apiList
          this.selectedRowKeys = this.configForm.apiList
          this.configForm.apiList.forEach(row => {
            getInfo(row).then(response => {
              this.selectedRows.push(response.data)
            })
          })
          this.loading2 = false
        })
      }
    },
    initForm() { // 重置所有表单对象
      this.configForm.app = {
        id: null,
        appId: null,
        name: null,
        secKey: null,
        mobile: null,
        contact: null,
        remark: null,
        createTime: null,
        createBy: null
      }
      this.configForm.apiList = []
    },
    asideChange() {
      this.asideStatus = !this.asideStatus 
      if (this.asideStatus) {
        this.asideOpen = true
      } else {
        this.asideOpen = false
      }
    },
    getModuleData() { // 获取目录数据
      this.loading1 = true
      listModule().then(response => {
        this.contentsData = response.rows
        generateList(this.contentsData)
        this.expandedKeys = []
        this.loading1 = false
      })
    },
    getInfoData() { // 获取表格数据
      this.loading2 = true
      this.infoParams.pageNum = this.pageForm.pageNum
      this.infoParams.pageSize = this.pageForm.pageSize
      listInfo(this.infoParams).then(response => {
        this.total = response.total
        this.tableData = response.rows.map(item => {
          return {
            ...item,
            key: item.id,
          }
        })
        this.loading2 = false
      })
    },
    getShow() {
      return this.show
    },
    cancel() { // 关闭弹窗
      this.show = false
      this.$emit('showChange', this.show)
    },
    onSelectChange(selectedRowKeys, selectedRows) { // 选中数据改变
      this.selectedRows = selectedRows
      this.selectedRowKeys = selectedRowKeys
      this.configForm.apiList = this.selectedRowKeys
    },
    handleNodeClick(key, e) { // 点击目录节点
      this.vueId = key[0]
      this.infoParams.moduleId = key[0]
      this.getInfoData()
    },
    submitForm() {
      this.$refs["configForm"].validate(valid => {
        if (valid) {
          if (this.id == null) { // 新增
            addConfig(this.configForm).then(response => {
              this.cancel()
            })
          } else { // 编辑
            editConfig(this.configForm).then(response => {
              this.cancel()
            })
          }
        }
      })
    },
    handleCurrentChange() { // 切换页面
      this.infoParams.moduleId = this.vueId
      this.infoParams.pageNum = this.pageForm.pageNum
      this.infoParams.pageSize = this.pageForm.pageSize
      this.getInfoData()
    },
    handleSizeChange(cur ,val) { // 切换页面大小
      this.infoParams.moduleId = this.vueId
      this.pageForm.pageNum = 1
      this.pageForm.pageSize = val
      this.infoParams.pageNum = this.pageForm.pageNum
      this.infoParams.pageSize = this.pageForm.pageSize
      this.getInfoData()
    },
    onExpand (expandedKeys) { // 展开节点
      this.expandedKeys.push(expandedKeys)
      this.autoExpandParent = false
    },
    onSearch(e){
      if(this.searchValue === '') {
        this.getModuleData()
        return
      }
      const value = e.target.value
      const expandedKeys = dataList
      .map((item) => {
        if (item.moduleCname.indexOf(value) > -1) {
          return getParentKey(item.id, this.contentsData)
        }
        return null
      })
      .filter((item, i, self) => item && self.indexOf(item) === i)
      setStyleDisplay(value, this.contentsData)
      Object.assign(this, {
        expandedKeys,
        autoExpandParent: true,
      })
    }
  }
}
</script>
<style>
.aside_open_close{
  position: relative;
  width: 18px;
  height: 60px;
  line-height: 60px;
  color: rgb(131,159,163);
  background-color: rgb(255, 255, 255);
  border-radius: 0 6px 6px 0;
  border: 1px rgb(198, 196, 196) solid;
  font-size: 20px;
  cursor: pointer;
}
</style>
